package com.dd.cloud.common.utils;

import com.alibaba.fastjson.JSONObject;
import com.dd.cloud.common.annotate.ForUpdate;

import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;


public class BeanUtils {
    /**
     * 获取两个bean变更内容
     * 支持两个不相同的bean类型
     * 使用@ForUpdate注解进行匹配
     *
     * @param newBean 修改后的bean
     * @param oldBean 修改前的bean
     * @param <T>     bean类型
     * @return json数据
     */
    public static <T> String getChangedFields(T newBean, T oldBean) {
        Field[] fields1 = newBean.getClass().getDeclaredFields();
        Field[] fields2 = oldBean.getClass().getDeclaredFields();
        Map<String, Field> map = Arrays.stream(fields2).collect(Collectors.toMap(t -> {
            if (t.isAnnotationPresent(ForUpdate.class)) {
                String fieldName;
                return (fieldName = t.getAnnotation(ForUpdate.class).fieldName()).equals("") ? t.getName() : fieldName;
            }
            return null;
        }, t -> t));
        JSONObject jsonObj = new JSONObject();
        for (Field field1 : fields1) {
            if (field1.isAnnotationPresent(ForUpdate.class)) {
                ForUpdate forUpdate = field1.getAnnotation(ForUpdate.class);
                String fieldName = forUpdate.fieldName();
                Field field2 = map.get(fieldName);
                if ("".equals(fieldName)) {
                    fieldName = field1.getName();
                    field2 = map.get(fieldName);
                }
                field1.setAccessible(true);
                field2.setAccessible(true);
                try {
                    Object newValue = field1.get(newBean);
                    Object oldValue = field2.get(oldBean);
                    if ((newValue == null || "".equals(newValue)) && (oldValue == null || "".equals(oldValue))) {
                        continue;
                    }
                    if (!Objects.equals(newValue, oldValue)) {
                        jsonObj.put(fieldName, newValue);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
        return jsonObj.toJSONString();
    }
}